home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 006 / microemacs / search.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  6KB  |  243 lines

  1. /*
  2.  * The functions in this file implement commands that search in the forward
  3.  * and backward directions. There are no special characters in the search
  4.  * strings. Probably should have a regular expression search, or something
  5.  * like that.
  6.  *
  7.  * REVISION HISTORY:
  8.  *
  9.  * ?    Steve Wilhite, 1-Dec-85
  10.  *      - massive cleanup on code.
  11.  */
  12.  
  13. #include        <stdio.h>
  14. #include        "ed.h"
  15.  
  16. /*
  17.  * Search forward. Get a search string from the user, and search, beginning at
  18.  * ".", for the string. If found, reset the "." to be just after the match
  19.  * string, and [perhaps] repaint the display. Bound to "C-S".
  20.  */
  21. forwsearch(f, n)
  22.     {
  23.     register LINE *clp;
  24.     register int cbo;
  25.     register LINE*tlp;
  26.     register int tbo;
  27.     register int c;
  28.     register char *pp;
  29.     register int s;
  30.  
  31.     if ((s = readpattern("Search")) != TRUE)
  32.         return (s);
  33.  
  34.     clp = curwp->w_dotp;
  35.     cbo = curwp->w_doto;
  36.  
  37.     while (clp != curbp->b_linep)
  38.         {
  39.         if (cbo == llength(clp))
  40.             {
  41.             clp = lforw(clp);
  42.             cbo = 0;
  43.             c = '\n';
  44.             }
  45.         else
  46.             c = lgetc(clp, cbo++);
  47.  
  48.         if (eq(c, pat[0]) != FALSE)
  49.             {
  50.             tlp = clp;
  51.             tbo = cbo;
  52.             pp  = &pat[1];
  53.  
  54.             while (*pp != 0)
  55.                 {
  56.                 if (tlp == curbp->b_linep)
  57.                     goto fail;
  58.  
  59.                 if (tbo == llength(tlp))
  60.                     {
  61.                     tlp = lforw(tlp);
  62.                     tbo = 0;
  63.                     c = '\n';
  64.                     }
  65.                 else
  66.                     c = lgetc(tlp, tbo++);
  67.  
  68.                 if (eq(c, *pp++) == FALSE)
  69.                     goto fail;
  70.                 }
  71.  
  72.             curwp->w_dotp  = tlp;
  73.             curwp->w_doto  = tbo;
  74.             curwp->w_flag |= WFMOVE;
  75.             return (TRUE);
  76.             }
  77. fail:;
  78.         }
  79.  
  80.     mlwrite("Not found");
  81.     return (FALSE);
  82.     }
  83.  
  84. /*
  85.  * Reverse search. Get a search string from the user, and search, starting at
  86.  * "." and proceeding toward the front of the buffer. If found "." is left
  87.  * pointing at the first character of the pattern [the last character that was
  88.  j matched]. Bound to "C-R".
  89.  */
  90. backsearch(f, n)
  91.     {
  92.     register LINE *clp;
  93.     register int cbo;
  94.     register LINE *tlp;
  95.     register int tbo;
  96.     register int c;
  97.     register char *epp;
  98.     register char *pp;
  99.     register int s;
  100.  
  101.     if ((s = readpattern("Reverse search")) != TRUE)
  102.         return (s);
  103.  
  104.     for (epp = &pat[0]; epp[1] != 0; ++epp)
  105.         ;
  106.  
  107.     clp = curwp->w_dotp;
  108.     cbo = curwp->w_doto;
  109.  
  110.     for (;;)
  111.         {
  112.         if (cbo == 0)
  113.             {
  114.             clp = lback(clp);
  115.  
  116.             if (clp == curbp->b_linep)
  117.                 {
  118.                 mlwrite("Not found");
  119.                 return (FALSE);
  120.                 }
  121.  
  122.             cbo = llength(clp)+1;
  123.             }
  124.  
  125.         if (--cbo == llength(clp))
  126.             c = '\n';
  127.         else
  128.             c = lgetc(clp, cbo);
  129.  
  130.         if (eq(c, *epp) != FALSE)
  131.             {
  132.             tlp = clp;
  133.             tbo = cbo;
  134.             pp  = epp;
  135.  
  136.             while (pp != &pat[0])
  137.                 {
  138.                 if (tbo == 0)
  139.                     {
  140.                     tlp = lback(tlp);
  141.                     if (tlp == curbp->b_linep)
  142.                         goto fail;
  143.  
  144.                     tbo = llength(tlp)+1;
  145.                     }
  146.  
  147.                 if (--tbo == llength(tlp))
  148.                     c = '\n';
  149.                 else
  150.                     c = lgetc(tlp, tbo);
  151.  
  152.                 if (eq(c, *--pp) == FALSE)
  153.                     goto fail;
  154.                 }
  155.  
  156.             curwp->w_dotp  = tlp;
  157.             curwp->w_doto  = tbo;
  158.             curwp->w_flag |= WFMOVE;
  159.             return (TRUE);
  160.             }
  161. fail:;
  162.         }
  163.     }
  164.  
  165. /*
  166.  * Compare two characters. The "bc" comes from the buffer. It has it's case
  167.  * folded out. The "pc" is from the pattern.
  168.  */
  169. eq(bc, pc)
  170.     int bc;
  171.     int pc;
  172.     {
  173.     if (bc>='a' && bc<='z')
  174.         bc -= 0x20;
  175.  
  176.     if (pc>='a' && pc<='z')
  177.         pc -= 0x20;
  178.  
  179.     if (bc == pc)
  180.         return (TRUE);
  181.  
  182.     return (FALSE);
  183.     }
  184.  
  185. /*
  186.  * Read a pattern. Stash it in the external variable "pat". The "pat" is not
  187.  * updated if the user types in an empty line. If the user typed an empty line,
  188.  * and there is no old pattern, it is an error. Display the old pattern, in the
  189.  * style of Jeff Lomicka. There is some do-it-yourself control expansion.
  190.  */
  191. readpattern(prompt)
  192.     char *prompt;
  193.     {
  194.     register char *cp1;
  195.     register char *cp2;
  196.     register int c;
  197.     register int s;
  198.     char tpat[NPAT+20];
  199.  
  200.     cp1 = &tpat[0];                     /* Copy prompt */
  201.     cp2 = prompt;
  202.  
  203.     while ((c = *cp2++) != '\0')
  204.         *cp1++ = c;
  205.  
  206.     if (pat[0] != '\0')                 /* Old pattern */
  207.         {
  208.         *cp1++ = ' ';
  209.         *cp1++ = '[';
  210.         cp2 = &pat[0];
  211.  
  212.         while ((c = *cp2++) != 0)
  213.             {
  214.             if (cp1 < &tpat[NPAT+20-6]) /* "??]: \0" */
  215.                 {
  216.                 if (c<0x20 || c==0x7F) {
  217.                     *cp1++ = '^';
  218.                     c ^= 0x40;
  219.                     }
  220.                 else if (c == '%')      /* Map "%" to */
  221.                     *cp1++ = c;         /* "%%". */
  222.  
  223.                 *cp1++ = c;
  224.                 }
  225.             }
  226.  
  227.         *cp1++ = ']';
  228.         }
  229.  
  230.     *cp1++ = ':';                       /* Finish prompt */
  231.     *cp1++ = ' ';
  232.     *cp1++ = '\0';
  233.     s = mlreply(tpat, tpat, NPAT);      /* Read pattern */
  234.  
  235.     if (s == TRUE)                      /* Specified */
  236.         strcpy(pat, tpat);
  237.     else if (s == FALSE && pat[0] != 0)         /* CR, but old one */
  238.         s = TRUE;
  239.  
  240.     return (s);
  241.     }
  242.  
  243.